﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using PloobsEngine.Physics.XJigLib;
using PloobsEngine.Publishers;
using PloobsEngine.Entity;

namespace PloobsEngine.Behaviors
{
    public class HardCharacterMovimentationBehavior : IBehavior
    {
        private float amount = 6f;        
        private CharacterMovimentationAction cma;
        private static ActionPublishInformation apiB = new ActionPublishInformation(NAME, MOVEBACK,null);
        private static ActionPublishInformation apiF = new ActionPublishInformation(NAME, MOVEFRONT,null);
        private static ActionPublishInformation apiL = new ActionPublishInformation(NAME, MOVELEFT,null);
        private static ActionPublishInformation apiR = new ActionPublishInformation(NAME, MOVERIGHT,null);
        private static ActionPublishInformation apiS = new ActionPublishInformation(NAME, STOPPED,null);
        private static ActionPublishInformation apiStopping = new ActionPublishInformation(NAME, STOPPING,null);
        private HardMovimentationUpdate hupdate;        

        public HardCharacterMovimentationBehavior(EngineStuff engine, CharacterObject character)
        {
            cma = new CharacterMovimentationAction(character);

            hupdate = new HardMovimentationUpdate(engine, this);
            hupdate.Start();
        }

        public HardCharacterMovimentationBehavior(EngineStuff engine, CharacterObject character, float speed, float rot)
            : this(engine,character,speed)
        {
            cma.setRotation(rot);
        }

        public HardCharacterMovimentationBehavior(EngineStuff engine, CharacterObject character, float speed)
        {
            cma = new CharacterMovimentationAction(character);
            this.amount = speed * 10;
            hupdate = new HardMovimentationUpdate(engine, this);
            hupdate.Start();
        }

        public void setSpeed(float amount)
        {
            this.amount = amount ;
        }

        #region IBehavior Members
        float multiplier = 1;
        CharacterMovimentationAction.DIRECTION dir;

        public void setMultiplier(float mult)
        {
            lock (this)
            {
                this.multiplier = mult;
            }
        }

        public void PerformBehavior(String state, object data)
        {            
            dir = CharacterMovimentationAction.DIRECTION.Stopping;

            switch (state)
            {
                case MOVERIGHT:
                    dir = CharacterMovimentationAction.DIRECTION.Right;
                    Notify(apiR);
                    //hupdate.ShouldUpdate = false;
                    break;
                case MOVELEFT:
                    dir = CharacterMovimentationAction.DIRECTION.Left;                    
                    Notify(apiL);
                    //hupdate.ShouldUpdate = false;
                    break;
                case MOVEFRONT:
                    dir = CharacterMovimentationAction.DIRECTION.Front;                    
                    Notify(apiF);
                    hupdate.ShouldUpdate = false;
                    break;
                case MOVEBACK:
                    dir =  CharacterMovimentationAction.DIRECTION.Back;
                    Notify(apiB);
                    hupdate.ShouldUpdate = false;
                    break;
                case null:
                    dir = CharacterMovimentationAction.DIRECTION.Stop;                    
                    Notify(apiS);
                    hupdate.ShouldUpdate = false;
                    break;
            }
            cma.setSpeed(amount);
            cma.setDirection(dir);
            cma.Action();
        }

        #endregion

        private ISubject _sub = new ConcreteSubject();
        #region ISubject Members
        public int ObserverNumber()
        {
            return _sub.ObserverNumber();
        }

        public void Attach(IObserver obs)
        {
            _sub.Attach(obs);
        }

        public void Dettach(IObserver obs)
        {
            _sub.Dettach(obs);
        }

        public void DettachAll()
        {
            _sub.DettachAll();
        }

        public void Notify(object obj)
        {
            _sub.Notify(obj);
        }

        #endregion

        #region IBehavior Members


        public string BehaviorName
        {
            get { return NAME; }
        }
        public const String NAME = "CHARACTERMOVIMENTATIONBEHAVIOR";
        public const String MOVERIGHT = "MOVERIGHT";
        public const String MOVELEFT = "MOVELEFT";
        public const String MOVEFRONT = "MOVEFRONT";
        public const String MOVEBACK = "MOVEBACK";
        public const String MOVEJUMP = "MOVEJUMP";
        public const String STOPPED = "STOPPED";
        public const String STOPPING = "STOPPING";
        #endregion

        #region IBehavior Members


        private IList<IAction> actionsList = new List<IAction>();
        public IList<IAction> Actions
        {
            get { return actionsList; }
        }

        #endregion

        #region IBehavior Members


        public void Release()
        {
            EntityMapper.getInstance().RemoveEntity(hupdate);
        }

        #endregion
    }
}
